package com.celesea.configuration.security;

import com.celesea.configuration.ehcache.EhcacheProvider;
import com.celesea.configuration.security.bean.AuthorityUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Component
public class RedisAuthenticationFilter extends GenericFilterBean {

    private static Logger logger = LoggerFactory.getLogger(RedisAuthenticationFilter.class);

    @Autowired
    private CasRedisProvider casRedisProvider;
    @Autowired
    private EhcacheProvider ehcacheProvider;

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        // checkAuthenticationTimestamp(((HttpServletRequest) req).getSession());
        chain.doFilter(req, res);
    }

    public void checkAuthenticationTimestamp(HttpSession session) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            AuthorityUser authorityUser = (AuthorityUser) authentication.getPrincipal();
            String loginSessionId = authorityUser.getSsoLoginInfo().getLoginSessionId();
            if (ehcacheProvider.enableSkipCheckLoginInfo(loginSessionId)) {
                // 如果再本地缓存有效期内（默认：3s），认为登录信息没有过期，则不继续检测
                return;
            }
            Long updateTime = authorityUser.getUpdateTime();
            Long lastUpdateTime = casRedisProvider.getUserUpdateTime(loginSessionId);
            if (lastUpdateTime > updateTime) {
                logger.info("===>>>登录信息过期：sessionTime:{},redisTime:{},登录信息:{}", updateTime, lastUpdateTime, loginSessionId);
                session.invalidate();
                ehcacheProvider.clearUserTimeStamp(loginSessionId);
                ehcacheProvider.clearUserDetails(loginSessionId);
                throw new AccountExpiredException("登录信息已过期！！！！");
            } else {
                ehcacheProvider.cacheUserTimeStamp(loginSessionId);
            }
        }
    }
}
